/**
 * 智能请求队列服务
 * 根据优先级和网络状态动态调整请求顺序
 */

const logger = require('../utils/logger').logger;
const networkManager = require('../utils/network-manager');
const httpService = require('./http-service');
const envDetector = require('../utils/env-detector');

// 请求优先级
const PRIORITY = {
  HIGH: 3,    // 高优先级：关键操作如用户交互直接响应
  NORMAL: 2,  // 普通优先级：常规数据请求
  LOW: 1,     // 低优先级：统计数据、后台任务
  IDLE: 0     // 空闲优先级：只有在空闲时才处理的请求
};

// 请求状态
const STATUS = {
  PENDING: 'pending',      // 等待中
  PROCESSING: 'processing', // 处理中
  COMPLETED: 'completed',   // 已完成
  FAILED: 'failed',         // 失败
  CANCELED: 'canceled'      // 已取消
};

/**
 * 智能请求队列类
 */
class RequestQueue {
  constructor() {
    // 请求队列
    this.queue = [];
    
    // 并发请求数量限制
    this.concurrentLimit = 6;
    
    // 当前正在处理的请求数量
    this.processingCount = 0;
    
    // 是否正在处理队列
    this.isProcessing = false;
    
    // 是否在开发者工具中运行
    this.isDevTools = envDetector.isDevTools();
    
    // 网络状态变化处理
    this._initNetworkListener();
    
    logger.info('智能请求队列初始化完成');
  }
  
  /**
   * 初始化网络状态监听
   * @private
   */
  _initNetworkListener() {
    networkManager.addCallback(this._handleNetworkChange.bind(this));
  }
  
  /**
   * 处理网络状态变化
   * @param {string} networkType 新的网络类型
   * @private
   */
  _handleNetworkChange(networkType) {
    logger.info(`请求队列: 网络状态变为 ${networkType}，重新排序队列`);
    
    // 如果网络断开，暂停处理队列
    if (networkType === 'none') {
      this.isProcessing = false;
      return;
    }
    
    // 根据网络类型调整并发请求限制
    if (networkType === 'wifi') {
      this.concurrentLimit = 6;
    } else if (['4g', '5g'].includes(networkType)) {
      this.concurrentLimit = 4;
    } else {
      this.concurrentLimit = 2;
    }
    
    // 重新排序队列
    this._sortQueue();
    
    // 如果队列未在处理中，启动处理
    if (!this.isProcessing && this.queue.length > 0) {
      this._processQueue();
    }
  }
  
  /**
   * 添加请求到队列
   * @param {Object} options 请求选项
   * @param {string} options.url 请求URL
   * @param {string} options.method 请求方法
   * @param {Object} options.data 请求数据
   * @param {Object} options.header 请求头
   * @param {number} options.priority 请求优先级，默认为普通优先级
   * @param {number} options.timeout 超时时间
   * @param {boolean} options.retry 是否在失败时重试
   * @param {number} options.maxRetries 最大重试次数
   * @param {Function} options.onProgress 进度回调
   * @param {Function} options.onSuccess 成功回调
   * @param {Function} options.onFail 失败回调
   * @returns {string} 请求ID
   */
  addRequest(options) {
    const requestId = `req_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
    
    // 确保优先级有效
    const priority = options.priority !== undefined ? 
      options.priority : PRIORITY.NORMAL;
    
    // 创建请求对象
    const request = {
      id: requestId,
      url: options.url,
      method: options.method || 'GET',
      data: options.data || {},
      header: options.header || {},
      priority: priority,
      timeout: options.timeout || 30000,
      retry: options.retry !== false,
      maxRetries: options.maxRetries || 3,
      retryCount: 0,
      status: STATUS.PENDING,
      createdAt: Date.now(),
      networkType: networkManager.getNetworkType(),
      onProgress: options.onProgress,
      onSuccess: options.onSuccess,
      onFail: options.onFail,
      result: null,
      error: null
    };
    
    // 添加到队列
    this.queue.push(request);
    
    logger.debug(`请求队列: 添加请求 [${requestId}]，优先级: ${priority}，当前队列长度: ${this.queue.length}`);
    
    // 排序队列
    this._sortQueue();
    
    // 尝试处理队列
    this._processQueue();
    
    return requestId;
  }
  
  /**
   * 排序请求队列
   * @private
   */
  _sortQueue() {
    // 获取当前网络类型
    const networkType = networkManager.getNetworkType();
    
    this.queue.sort((a, b) => {
      // 首先按照优先级排序（高到低）
      if (a.priority !== b.priority) {
        return b.priority - a.priority;
      }
      
      // 优先级相同时，根据网络环境和请求特性排序
      if (networkType === 'wifi') {
        // WiFi环境下，优先处理较大的请求
        return b.data.size || 0 - (a.data.size || 0);
      } else if (['4g', '5g'].includes(networkType)) {
        // 4G/5G环境下，按照创建时间排序
        return a.createdAt - b.createdAt;
      } else {
        // 较差的网络环境下，优先处理较小的请求
        return (a.data.size || 0) - (b.data.size || 0);
      }
    });
  }
  
  /**
   * 处理请求队列
   * @private
   */
  _processQueue() {
    // 如果已经在处理队列或者网络断开，则不处理
    if (this.isProcessing || networkManager.getNetworkType() === 'none') {
      return;
    }
    
    this.isProcessing = true;
    
    // 处理请求队列函数
    const processNext = () => {
      // 找出所有等待中的请求
      const pendingRequests = this.queue.filter(req => req.status === STATUS.PENDING);
      
      // 如果没有等待中的请求或者达到并发限制，则暂停处理
      if (pendingRequests.length === 0 || this.processingCount >= this.concurrentLimit) {
        this.isProcessing = false;
        return;
      }
      
      // 获取下一个要处理的请求
      const nextRequest = pendingRequests[0];
      
      // 更新请求状态
      nextRequest.status = STATUS.PROCESSING;
      this.processingCount++;
      
      logger.debug(`请求队列: 开始处理请求 [${nextRequest.id}]，当前处理中: ${this.processingCount}/${this.concurrentLimit}`);
      
      // 在开发者工具中模拟请求处理
      if (this.isDevTools) {
        setTimeout(() => {
          // 模拟成功响应
          nextRequest.status = STATUS.COMPLETED;
          nextRequest.result = { success: true, data: { message: '模拟响应数据' } };
          
          // 执行成功回调
          if (typeof nextRequest.onSuccess === 'function') {
            try {
              nextRequest.onSuccess(nextRequest.result);
            } catch (e) {
              logger.error(`请求队列: 执行成功回调出错 [${nextRequest.id}]`, e);
            }
          }
          
          // 更新处理计数并移除请求
          this.processingCount--;
          this._removeRequest(nextRequest.id);
          
          // 继续处理队列
          processNext();
        }, 500);
        
        // 继续处理其他请求
        processNext();
        return;
      }
      
      // 执行实际的HTTP请求
      const requestConfig = {
        url: nextRequest.url,
        data: nextRequest.data,
        header: nextRequest.header,
        method: nextRequest.method,
        timeout: nextRequest.timeout
      };
      
      // 使用httpService执行请求
      httpService.request(requestConfig)
        .then(result => {
          // 更新请求状态
          nextRequest.status = STATUS.COMPLETED;
          nextRequest.result = result;
          
          // 执行成功回调
          if (typeof nextRequest.onSuccess === 'function') {
            try {
              nextRequest.onSuccess(result);
            } catch (e) {
              logger.error(`请求队列: 执行成功回调出错 [${nextRequest.id}]`, e);
            }
          }
          
          logger.debug(`请求队列: 请求成功完成 [${nextRequest.id}]`);
        })
        .catch(error => {
          // 处理请求失败
          logger.warn(`请求队列: 请求失败 [${nextRequest.id}]`, error);
          
          // 判断是否需要重试
          if (nextRequest.retry && nextRequest.retryCount < nextRequest.maxRetries) {
            // 增加重试计数
            nextRequest.retryCount++;
            
            // 将状态设回等待中
            nextRequest.status = STATUS.PENDING;
            
            logger.info(`请求队列: 准备重试请求 [${nextRequest.id}]，第 ${nextRequest.retryCount} 次`);
          } else {
            // 不再重试，标记为失败
            nextRequest.status = STATUS.FAILED;
            nextRequest.error = error;
            
            // 执行失败回调
            if (typeof nextRequest.onFail === 'function') {
              try {
                nextRequest.onFail(error);
              } catch (e) {
                logger.error(`请求队列: 执行失败回调出错 [${nextRequest.id}]`, e);
              }
            }
            
            // 移除请求
            this._removeRequest(nextRequest.id);
          }
        })
        .finally(() => {
          // 如果请求已完成或失败，减少处理计数
          if (nextRequest.status === STATUS.COMPLETED || nextRequest.status === STATUS.FAILED) {
            this.processingCount--;
          }
          
          // 继续处理队列
          processNext();
        });
      
      // 继续处理其他请求（并发）
      processNext();
    };
    
    // 开始处理队列
    processNext();
  }
  
  /**
   * 从队列中移除请求
   * @param {string} requestId 请求ID
   * @private
   */
  _removeRequest(requestId) {
    const index = this.queue.findIndex(req => req.id === requestId);
    if (index !== -1) {
      this.queue.splice(index, 1);
      logger.debug(`请求队列: 移除请求 [${requestId}]，当前队列长度: ${this.queue.length}`);
    }
  }
  
  /**
   * 取消请求
   * @param {string} requestId 请求ID
   * @returns {boolean} 是否成功取消
   */
  cancelRequest(requestId) {
    const request = this.queue.find(req => req.id === requestId);
    
    if (!request) {
      logger.warn(`请求队列: 无法取消请求 [${requestId}]，请求不存在`);
      return false;
    }
    
    // 只能取消等待中的请求
    if (request.status === STATUS.PENDING) {
      request.status = STATUS.CANCELED;
      
      // 移除请求
      this._removeRequest(requestId);
      
      logger.info(`请求队列: 成功取消请求 [${requestId}]`);
      return true;
    }
    
    logger.warn(`请求队列: 无法取消请求 [${requestId}]，当前状态: ${request.status}`);
    return false;
  }
  
  /**
   * 获取请求状态
   * @param {string} requestId 请求ID
   * @returns {Object|null} 请求状态对象或null
   */
  getRequestStatus(requestId) {
    const request = this.queue.find(req => req.id === requestId);
    
    if (!request) {
      return null;
    }
    
    return {
      id: request.id,
      status: request.status,
      priority: request.priority,
      createdAt: request.createdAt,
      retryCount: request.retryCount
    };
  }
  
  /**
   * 获取队列统计信息
   * @returns {Object} 队列统计信息
   */
  getQueueStats() {
    const pendingCount = this.queue.filter(req => req.status === STATUS.PENDING).length;
    const processingCount = this.processingCount;
    
    return {
      total: this.queue.length,
      pending: pendingCount,
      processing: processingCount,
      concurrentLimit: this.concurrentLimit,
      networkType: networkManager.getNetworkType()
    };
  }
  
  /**
   * 清空请求队列
   */
  clearQueue() {
    // 只清除等待中的请求
    const pendingRequests = this.queue.filter(req => req.status === STATUS.PENDING);
    
    pendingRequests.forEach(request => {
      request.status = STATUS.CANCELED;
      
      // 执行失败回调
      if (typeof request.onFail === 'function') {
        try {
          request.onFail({ errorMsg: '请求被取消' });
        } catch (e) {
          logger.error(`请求队列: 执行失败回调出错 [${request.id}]`, e);
        }
      }
    });
    
    // 从队列中移除所有已取消的请求
    this.queue = this.queue.filter(req => req.status !== STATUS.CANCELED);
    
    logger.info(`请求队列: 已清空等待中的请求，移除了 ${pendingRequests.length} 个请求`);
  }
  
  /**
   * 调整请求优先级
   * @param {string} requestId 请求ID
   * @param {number} newPriority 新的优先级
   * @returns {boolean} 是否成功调整
   */
  adjustPriority(requestId, newPriority) {
    const request = this.queue.find(req => req.id === requestId);
    
    if (!request) {
      logger.warn(`请求队列: 无法调整请求 [${requestId}] 的优先级，请求不存在`);
      return false;
    }
    
    // 只能调整等待中的请求
    if (request.status === STATUS.PENDING) {
      request.priority = newPriority;
      
      // 重新排序队列
      this._sortQueue();
      
      logger.info(`请求队列: 成功调整请求 [${requestId}] 的优先级为 ${newPriority}`);
      return true;
    }
    
    logger.warn(`请求队列: 无法调整请求 [${requestId}] 的优先级，当前状态: ${request.status}`);
    return false;
  }
}

// 导出优先级枚举
RequestQueue.PRIORITY = PRIORITY;

// 导出单例
const requestQueue = new RequestQueue();
module.exports = requestQueue; 